package cn.web.web_module.service.impl;

import cn.itcast.mapper.*;
import cn.itcast.pojo.*;
import cn.itcast.util.DoubleUtils;
import cn.itcast.util.ResponseEntity;
import cn.web.web_module.service.HorsemanPayService;
import com.sun.org.apache.xpath.internal.operations.Bool;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @Author: 张松
 * @Description:
 * @Date: Created in 14:26 2020/11/25
 * @Modified By:
 */
@Service
@Slf4j
public class HorsemanPayServiceImpl implements HorsemanPayService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private orderMapper orderMapper;

    @Autowired
    private userMapper userMapper;

    @Autowired
    private horsemanMapper horsemanMapper;

    @Autowired
    private accountMapper accountMapper;

    @Autowired
    private earningsMapper earningsMapper;

    @Autowired
    private infoMapper infoMapper;

    @Autowired
    private orderItemMapper orderItemMapper;

    @Autowired
    private classsifyMapper classsifyMapper;


    private String OrderNumber; //账户订单号




    /**
     *
     * @Description: 骑手支付
     *
     * @auther: 张松
     * @date: 14:20 2020/11/25
     * @param: [orderId, openId, price]
     * @return: cn.itcast.util.ResponseEntity
     *
     */
    @Override
    public ResponseEntity PayByOrder(Integer orderId, String horsemanOpenId, Double price) {
        order order = orderMapper.selectByPrimaryKey(orderId);
        try {
        ResponseEntity responseEntity = IfPayByOrder(orderId, horsemanOpenId, price);
        if(responseEntity.getCode()!=200){
            return responseEntity;
        }
        //判断是否可以支付
        if (!UserChargeMoney(orderId)){
            return new ResponseEntity(300,"用户收款失败");
        }
        //用户收款
        if (!horsemanPay(orderId,horsemanOpenId,price)){
            return  new ResponseEntity(300,"骑手支付失败");
        }
        //骑手支付
        if (!distributionMoney(orderId)){
            return new ResponseEntity(300,"用户分销失败");
        }
        account accountHorseman = accountMapper.selectByAccountOpenid(horsemanOpenId);
        Double accountMoneyBalance = accountHorseman.getAccountMoneyBalance();
            //分销佣金
        order.setOrderState("已完成");
        order.setPayTime(new Date());
        order.setHorsemanBalance(accountMoneyBalance);
        int i = orderMapper.updateByPrimaryKeySelective(order);
        if (i>0){
            return new ResponseEntity(200,"订单支付成功");
        }else {
            return new ResponseEntity(300,"订单支付失败");
        }
        }finally {
            if (!stringRedisTemplate.opsForValue().get(order.getOrderNumber()).isEmpty()){
                stringRedisTemplate.delete(order.getOrderNumber());
            }
        }
    }

    // 一二级分销获取奖金
    private boolean distributionMoney(Integer orderId) {
        order order = orderMapper.selectByPrimaryKey(orderId);
        List<orderItem> orderItemList = orderItemMapper.findOrderId(order.getId());
        String userOpenId = order.getOpenId();
        user user = userMapper.selectFindOneUser(userOpenId);
        String userOneDistributionOpenid = user.getUserOneDistribution();   //一级推广人openid
        String userTwoDistributionOpenid = user.getUserTwoDistribution();   //二级推广人openid
        if (userOneDistributionOpenid!=null && !userOneDistributionOpenid.isEmpty()){
            account oneDistributionAccount = accountMapper.selectByAccountOpenid(userOneDistributionOpenid);    //一级分销用户
            Double OneDistribution = accountOneDistributionMoney(orderItemList);       //一级分销金额
            Double accountMoneyBalance =DoubleUtils.add(oneDistributionAccount.getAccountMoneyBalance(),OneDistribution);  //用户增加后的账户余额
            Double accountEarningsOneDistribution = oneDistributionAccount.getAccountEarningsOneDistribution(); //用户之前的一级分销记录
            Double accountEarningsOne = DoubleUtils.add(accountEarningsOneDistribution, OneDistribution); //增加的一级分销金额
            oneDistributionAccount.setAccountEarningsOneDistribution(accountEarningsOne);   //设置账户表一级分销金额累计
            oneDistributionAccount.setAccountMoneyBalance(accountMoneyBalance);     //设置一级分销用户金额
            int i = accountMapper.updateByPrimaryKeySelective(oneDistributionAccount);
            if (i>0){
                earnings earnings = new earnings();
                earnings.setAccountId(oneDistributionAccount.getAccountId());
                earnings.setName(oneDistributionAccount.getAccountName());
                earnings.setOpenid(userOneDistributionOpenid);
                earnings.setSource("一级分销");
                earnings.setNumber(order.getOrderNumber());
                earnings.setNum(OneDistribution);
                earnings.setState("已出账");
                earnings.setEarningsExplain("一级分销");
                //一级分销用户增加后的账户余额
                earnings.setCountnum(accountMoneyBalance);
                earningsMapper.insertSelective(earnings);
                info info = new info();
                info.setInfoType("订单消息");
                info.setOpenid(userOneDistributionOpenid);
                info.setUserOpenid(userOpenId);
                info.setInfoTitle("一级分销佣金到账了");
                info.setInfoContent("您推广的用户："+user.getUserName()+"，成功完成订单，您获得"+OneDistribution+"元佣金，快去钱包查看吧。");
                infoMapper.insertSelective(info);
                log.info("一级推广人:"+userOneDistributionOpenid+"获得佣金成功,佣金为:"+OneDistribution);
            }

        }
        if (userTwoDistributionOpenid!=null && !userTwoDistributionOpenid.isEmpty()){
            account twoDistributionAccount = accountMapper.selectByAccountOpenid(userTwoDistributionOpenid);    //二级分销用户
            Double twoDistribution=accountTWODistributionMoney(orderItemList);  //二级分销金额
            Double accountMoneyBalance =DoubleUtils.add(twoDistributionAccount.getAccountMoneyBalance(),twoDistribution);//用户增加后的账户余额
            Double accountEarningsTwoDistribution = twoDistributionAccount.getAccountEarningsTwoDistribution();//用户之前的二级分销记录
            Double accountEarningsTwo = DoubleUtils.add(accountEarningsTwoDistribution, twoDistribution);   //增加的二级分销金额
            twoDistributionAccount.setAccountEarningsTwoDistribution(accountEarningsTwo);//设置账户表二级分销金额累计
            twoDistributionAccount.setAccountMoneyBalance(accountMoneyBalance);     //设置二级分销用户金额
            int i = accountMapper.updateByPrimaryKeySelective(twoDistributionAccount);
            if (i>0){
                earnings earnings = new earnings();
                earnings.setAccountId(twoDistributionAccount.getAccountId());
                earnings.setName(twoDistributionAccount.getAccountName());
                earnings.setOpenid(userOneDistributionOpenid);
                earnings.setSource("二级分销");
                earnings.setNumber(order.getOrderNumber());
                earnings.setNum(twoDistribution);
                earnings.setState("已出账");
                earnings.setEarningsExplain("二级分销");
                //二级分销用户增加后的账户余额
                earnings.setCountnum(accountMoneyBalance);
                earningsMapper.insertSelective(earnings);
                info info = new info();
                info.setInfoType("订单消息");
                info.setOpenid(userTwoDistributionOpenid);
                info.setUserOpenid(userOpenId);
                info.setInfoTitle("二级分销佣金到账了");
                info.setInfoContent("您推广的用户："+user.getUserName()+"，成功完成订单，您获得"+twoDistribution+"元佣金，快去钱包查看吧。");
                infoMapper.insertSelective(info);
                log.info("二级推广人:"+twoDistributionAccount+"获得佣金成功,佣金为:"+twoDistribution);
            }

        }
        return true;
    }

    //一级分销金额
    private Double accountOneDistributionMoney(List<orderItem> orderItemList) {
        Double  twoDistribution=0.0;
        for (orderItem orderItem : orderItemList) {
            List<classsify> classsify = classsifyMapper.findName(orderItem.getProductType());
                String previousProfit = classsify.get(0).getPreviousProfit();
                if (orderItem.getUnit().equals("kg")){
                    Double temp=DoubleUtils.mul(orderItem.getFinallyWeight(),Double.parseDouble(previousProfit));
                    twoDistribution=DoubleUtils.add(twoDistribution,temp);
                }else if (orderItem.getUnit().equals("台")){
                    Double temp=DoubleUtils.mul(orderItem.getSum(),Double.parseDouble(previousProfit));
                    twoDistribution=DoubleUtils.add(twoDistribution,temp);
                }

        }

        return  twoDistribution;
    }

    //二级分销金额
    private Double accountTWODistributionMoney(List<orderItem> orderItemList) {
        Double  OneDistribution=0.0;
        for (orderItem orderItem : orderItemList) {
            List<classsify> classsify = classsifyMapper.findName(orderItem.getProductType());
            String previousTwoProfit = classsify.get(0).getPreviousTwoProfit();
            if (orderItem.getUnit().equals("kg")){
                Double temp=DoubleUtils.mul(orderItem.getFinallyWeight(),Double.parseDouble(previousTwoProfit));
                OneDistribution=DoubleUtils.add(OneDistribution,temp);
            }else if (orderItem.getUnit().equals("台")){
                Double temp=DoubleUtils.mul(orderItem.getSum(),Double.parseDouble(previousTwoProfit));
                OneDistribution=DoubleUtils.add(OneDistribution,temp);
            }

        }

        return  OneDistribution;
    }

    //用户收款
    private boolean UserChargeMoney(Integer orderId) {
        order orderOne = orderMapper.selectByPrimaryKey(orderId);   //获取用户下单订单
        Double payOrderMoney = orderOne.getPayOrderMoney();         //用户需要增加的钱
        String UserOpenId = orderOne.getOpenId();
        account account = accountMapper.selectByAccountOpenid(UserOpenId);  //根据openid获取用户账号
        Double accountMoneyBalance = account.getAccountMoneyBalance();      //用户账户余额
        Double remainingBalance = DoubleUtils.add(accountMoneyBalance,payOrderMoney);     //用户账号上需要设置的金钱
        Double accountMoneyRental = account.getAccountMoneyRental();        //用户账户累计获得
        Double RentaladdMoney = DoubleUtils.add(accountMoneyRental, payOrderMoney);     //用户账号上需要设置的累计金额
        Double accountEarningsConsume = account.getAccountEarningsConsume();  //    用户消费收益
        Double Consumeadd = DoubleUtils.add(accountEarningsConsume, payOrderMoney);
        account.setAccountMoneyBalance(remainingBalance);       //用户账号赋值余额
        account.setAccountMoneyRental(RentaladdMoney);          //用户账号复制累计金额
        account.setAccountEarningsConsume(Consumeadd);          //用户账号赋值消费收益
        int i = accountMapper.updateByPrimaryKeySelective(account);
        if (i>0){
            this.OrderNumber = orderOne.getOrderNumber();
            userWriteEarning(account.getAccountId(),UserOpenId,OrderNumber,payOrderMoney,account.getAccountName(),remainingBalance); //用户收益记录表
            userWriteInfo(UserOpenId,orderOne.getHorsemanAccount(),payOrderMoney);  // 添加消息记录
            return true;
        }
        return false;
    }

    // 用户消息记录
    public Boolean userWriteInfo(String userOpenId,String horsemanAccount,Double payOrderMoney){
        info userInfo = new info();
        userInfo.setInfoType("订单消息");
        userInfo.setOpenid(userOpenId);
        userInfo.setUserOpenid(userOpenId);
        userInfo.setHorsemanOpenid(horsemanAccount);
        userInfo.setInfoTitle("订单金额到账了");
        userInfo.setInfoContent("您已成功完成订单，您获得"+payOrderMoney+"元环保佣金，快去钱包查看吧。");
        userInfo.setInfoImg("https://www.dhnep.cn:8181/dhn/icon/distribution-icon.png");
        userInfo.setInfoTime(new Date());
        int i = infoMapper.insertSelective(userInfo);
        if (i>1){
            log.info(userOpenId+"该用户消息记录生成成功");
            return true;
        }
        log.info(userOpenId+"该用户消息记录生成失败");
        return true;
    }

    // 用户收益记录表
    public Boolean userWriteEarning(Integer AccountId,String userOpenId,String orderNumber,Double payOrderMoney,String accountName,Double add){
        earnings userEarning = new earnings();
        userEarning.setAccountId(AccountId);
        userEarning.setName(accountName);
        userEarning.setOpenid(userOpenId);
        userEarning.setSource("订单消费");
        userEarning.setNumber(orderNumber);
        userEarning.setNum(payOrderMoney);
        userEarning.setState("已到账");
        userEarning.setEarningsExplain("骑手支付订单，获取收益");
        //用户增加后的账户余额
        userEarning.setCountnum(add);
        int i = earningsMapper.insertSelective(userEarning);
        if (i>0){
            log.info(userOpenId+"该用户收益表生成成功,订单号为:"+orderNumber);
            return true;
        }
        log.info(userOpenId+"该用户收益表生成失败,订单号为:"+orderNumber);
        return false;
    }


    //骑手支出记录表
    private Boolean horsemanPay(Integer orderId,String horsemanOpenId, Double price) {
        account account = accountMapper.selectByAccountOpenid(horsemanOpenId);  //根据骑手ID查找骑手账户
        Double accountMoneyBalance = account.getAccountMoneyBalance();
        Double remainingAccount = DoubleUtils.sub(accountMoneyBalance,price);    //扣钱
        account.setAccountMoneyBalance(remainingAccount);
        int i = accountMapper.updateByPrimaryKeySelective(account);
        if (i>0){
            horsemanEarning(account.getAccountId(),account.getAccountName(),horsemanOpenId,price,remainingAccount);//骑手支付记录表
            log.info("订单ID号:"+orderId+","+horsemanOpenId+"骑手支付成功,"+"支付"+price+"元");
            return true;
        }
        log.info("订单ID号:"+orderId+","+horsemanOpenId+"骑手支付"+price+"元失败");
        return false;
    }

    //骑手支付记录
    private Boolean horsemanEarning(Integer accountId, String accountName, String horsemanOpenId, Double price,Double sub) {
        earnings horsemanEarnings = new earnings();
        horsemanEarnings.setAccountId(accountId);
        horsemanEarnings.setName(accountName);
        horsemanEarnings.setOpenid(horsemanOpenId);
        horsemanEarnings.setSource("骑手支付");
        horsemanEarnings.setNumber(OrderNumber);
        horsemanEarnings.setState("已出账");
        horsemanEarnings.setNum(price);
        horsemanEarnings.setEarningsExplain("骑手支付订单，骑手支出");
        //骑手支出后的账户余额
        horsemanEarnings.setCountnum(sub);
        int i = earningsMapper.insertSelective(horsemanEarnings);
        if (i>0){
            log.info(horsemanOpenId+"该用户收益表生成成功,订单号为:"+OrderNumber);
            return true;
        }
        return false;

    }


    //判断是否可以支付
    public ResponseEntity IfPayByOrder(Integer orderId, String horsemanOpenId, Double price) {
        if (!ifOrderFinish(orderId)){
            return new ResponseEntity(300,"该订单已经支付完成");
        }
        //判断该订单是否已经支付
        if (!ifNullAndZero(orderId,horsemanOpenId,price)){
            return new ResponseEntity(300,"参数错误");
        }
        // 判断参数非空非0
        if (!ifAbsent(orderId)){
            return new ResponseEntity(400,"正在支付请稍后");
        }
        // 判断是否正在支付
        if (!ifHorseman(horsemanOpenId,price)){
            return new ResponseEntity(300,"骑手账户余额不足");
        }
        //判断骑手账户余额
        return new ResponseEntity(200,"可以支付");
    }

    //判断该订单是否已经支付
    private boolean ifOrderFinish(Integer orderId) {
        order order = orderMapper.selectByPrimaryKey(orderId);
        if (order.getOrderState().equals("已完成") || order.getOrderState().equals("已评价")){
            return false;
        }
        return true;
    }


    // 判断参数非空非0
    private boolean ifNullAndZero(Integer orderId, String horsemanOpenId, Double price) {
        Boolean ifNullAndZero=true;
        if (orderId==null||orderId==0) return false;
        if (horsemanOpenId==null||horsemanOpenId.isEmpty()) return false;
        if (price==null) return false;
        // 判断参数非空非0
        return ifNullAndZero;
    }

    // 判断是否重复支付
    private boolean ifAbsent(Integer orderId) {
        order order = orderMapper.selectByPrimaryKey(orderId);
        Boolean ifAbsent = stringRedisTemplate.opsForValue().setIfAbsent(order.getOrderNumber(), "1");
        stringRedisTemplate.expire(order.getOrderNumber(),3, TimeUnit.MINUTES);
        return ifAbsent;
    }

    //判断骑手账户余额
    private boolean ifHorseman(String horsemanOpenId,Double price) {
        Boolean ifPrice=true;
        account account = accountMapper.selectByAccountOpenid(horsemanOpenId);
        Double accountMoneyBalance = account.getAccountMoneyBalance();
        if (price>accountMoneyBalance){
            ifPrice=false;
        }
        return ifPrice;
    }


}
